
package model;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;

import utils.Command;
import utils.MyConnection;
import controller.ServerController;

public class ServerThreadModel extends Thread {
    
    private final Socket socket;
    private ObjectInputStream in;
    private ObjectOutputStream out;
    private String clientName;
    private ServerController serverController;
    
    public ServerThreadModel(Socket socket, ServerController serverController) {
        this.socket = socket;
        this.serverController = serverController;
        start();
    }
    
    public void run() {
        
        String[] received;
        
        try {
            out = new ObjectOutputStream(socket.getOutputStream());
            in = new ObjectInputStream(socket.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        
        do {
            received = MyConnection.receive(in);
            
            switch (received[MyConnection.COMMAND]) {
                case Command.CLIENT_NAME:
                    InetSocketAddress socketAddress = (InetSocketAddress) socket
                            .getRemoteSocketAddress();
                    InetAddress inetAddress = socketAddress.getAddress();
                    
                    clientName = inetAddress.getHostAddress();
                    try {
                        out.writeObject(String.valueOf(Command.OK));
                        out.flush();
                        out.reset();
                        serverController.addConnectedClient(clientName);
                    } catch (IOException e) {
                        received[MyConnection.COMMAND] = Command.EXIT;
                        e.printStackTrace();
                    }
                    break;
                case Command.CREATE_FILE:
                    try {
                        serverController.optionCreateFile(clientName,
                                received[MyConnection.MESSAGE], out);
                    } catch (IOException e) {
                        received[MyConnection.COMMAND] = Command.EXIT;
                        e.printStackTrace();
                    }
                    break;
                case Command.READ_FILE:
                    try {
                        serverController.optionReadFile(clientName,
                                received[MyConnection.MESSAGE], out);
                    } catch (IOException e) {
                        received[MyConnection.COMMAND] = Command.EXIT;
                        e.printStackTrace();
                    }
                    break;
                case Command.DELETE_FILE:
                    try {
                        serverController.optionDeleteFile(clientName,
                                received[MyConnection.MESSAGE], out);
                    } catch (IOException e) {
                        received[MyConnection.COMMAND] = Command.EXIT;
                        e.printStackTrace();
                    }
                    break;
                case Command.DOWNLOAD_FILE:
                    try {
                        serverController.optionDownloadFile(clientName,
                                received[MyConnection.MESSAGE], out);
                    } catch (IOException e) {
                        received[MyConnection.COMMAND] = Command.EXIT;
                        e.printStackTrace();
                    }
                    break;
                case Command.EDIT_FILE:
                    try {
                        serverController.optionEditFile(clientName,
                                received[MyConnection.MESSAGE], out);
                    } catch (IOException e) {
                        received[MyConnection.COMMAND] = Command.EXIT;
                        e.printStackTrace();
                    }
                    break;
                case Command.DB_ADD:
                    try {
                        serverController.optionDatabaseAdd(clientName,
                                received[MyConnection.MESSAGE], out);
                    } catch (IOException e) {
                        received[MyConnection.COMMAND] = Command.EXIT;
                        e.printStackTrace();
                    }
                    break;
                case Command.DB_REMOVE:
                    try {
                        serverController.optionDatabaseRemove(clientName,
                                received[MyConnection.MESSAGE], out);
                    } catch (IOException e) {
                        received[MyConnection.COMMAND] = Command.EXIT;
                        e.printStackTrace();
                    }
                    break;
                case Command.FINISH_USING:
                    try {
                        serverController.removeFileInUse(clientName,
                                received[MyConnection.MESSAGE], out);
                    } catch (IOException e) {
                        received[MyConnection.COMMAND] = Command.EXIT;
                        e.printStackTrace();
                    }
                    break;
                case Command.EXIT:
                    close();
                    break;
                default:
                    break;
            }
        } while (!received[MyConnection.COMMAND].equals(Command.EXIT));
        serverController.removeConnectedClient(clientName);
    }
    
    public void close() {
        try {
            socket.close();
            out.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public String getClientName() {
        return clientName;
    }
    
    public void setClientName(String clientName) {
        this.clientName = clientName;
    }
    
}
